
using FlatRedBall;
using FlatRedBall.Graphics;
using FlatRedBall.Math.Geometry;

using Microsoft.Xna.Framework.Audio;

using Xzipit.Utilities;
using FlatRedBall.Graphics.Animation;

namespace Xzipit.MenuObjects
{
    class LevelButton : MenuObject
    {
        #region Fields

        private int _level;
        private const int COLL_SIZE = 32;
        private Sprite _lock;
        private Sprite _levelNum1;
        private Sprite _levelNum10;

        // Keep the ContentManager for easy access:
        string _contentManagerName;
        private bool _partialFade;

        #endregion

        #region Properties

        public int Level
        {
            get { return _level; }
        }

        public override float Alpha
        {
            get { return _sprite.Alpha; }
            set
            {
                _sprite.Alpha = value;
                _levelNum1.Alpha = value;
                _levelNum10.Alpha = value;
                _lock.Alpha = value;
            }
        }

        public override float AlphaRate
        {
            get { return _sprite.AlphaRate; }
            set
            {
                _sprite.AlphaRate = value;
                _levelNum1.AlphaRate = value;
                _levelNum10.AlphaRate = value;
                _lock.AlphaRate = value;
            }
        }

        #endregion

        #region Methods

        // Constructor
        public LevelButton(string contentManagerName, int level)
        {
            // Set the ContentManagerName and call Initialize:
            _contentManagerName = contentManagerName;
            _level = level;
            _partialFade = false;

            // If you don't want to add to managers, make an overriding constructor
            Initialize(true);
        }

        protected override void Initialize(bool addToManagers)
        {
            // Here you can preload any content you will be using
            // like .scnx files or texture files.

            if (addToManagers)
            {
                AddToManagers(null);
            }
        }

        public override void AddToManagers(Layer layerToAddTo)
        {
            // Add the Entity to the SpriteManager
            // so it gets managed properly (velocity, acceleration, attachments, etc.)
            SpriteManager.AddPositionedObject(this);

            // Here you may want to add your objects to the engine.  Use layerToAddTo
            // when adding if your Entity supports layers.  Make sure to attach things
            // to this if appropriate.
            _sprite = SpriteManager.AddSprite(LoadColors());
            _sprite.AttachTo(this, false);
            SetColor(4);

            //_sprite.PixelScale();
            _sprite.ScaleX = 1.5f;
            _sprite.ScaleY = 1.5f;
            _sprite.Animate = false;

            //Polygon 
            this._collision = ShapeManager.AddAxisAlignedRectangle();
            this._collision.AttachTo(this, false);
            this._collision.ScaleX = 1.8f * _sprite.ScaleX;
            this._collision.ScaleY = 1.8f * _sprite.ScaleY;
            this._collision.Visible = false;

            int worldLevel = (_level - 1) % 12 + 1;

            if (worldLevel < 10)
            {
                _levelNum1 = SpriteManager.AddSprite(LoadNumber(worldLevel % 10));
                _levelNum1.AttachTo(this, false);
                _levelNum1.PixelScale();
                _levelNum1.RelativeY = -2.2f;
                _levelNum1.ScaleX *= 1.5f;
                _levelNum1.ScaleY *= 1.5f;

                _levelNum10 = SpriteManager.AddSprite(LoadNumber(worldLevel / 10));
                _levelNum10.AttachTo(this, false);
                _levelNum10.Visible = false;
            }
            else
            {
                _levelNum1 = SpriteManager.AddSprite(LoadNumber(worldLevel % 10));
                _levelNum1.AttachTo(this, false);
                _levelNum1.PixelScale();
                _levelNum1.RelativeX = 0.5f;
                _levelNum1.RelativeY = -2.2f;
                _levelNum1.ScaleX *= 1.5f;
                _levelNum1.ScaleY *= 1.5f;

                _levelNum10 = SpriteManager.AddSprite(LoadNumber(worldLevel / 10));
                _levelNum10.AttachTo(this, false);
                _levelNum10.PixelScale();
                _levelNum10.RelativeX = -0.5f;
                _levelNum10.RelativeY = -2.2f;
                _levelNum10.ScaleX *= 1.5f;
                _levelNum10.ScaleY *= 1.5f;
            }

            _enabled = true;
            _touchSound = FlatRedBallServices.Load<SoundEffect>(@"Content\Sound\button");

            _lock = SpriteManager.AddSprite(@"Content\MenuObjects\Rewards\lock");
            _lock.AttachTo(this, false);
            _lock.ScaleX = 1.5f;
            _lock.ScaleY = 1.5f;
            _lock.RelativeZ = 0.05f;
            _lock.Visible = false;
        }

        public override void Activity()
        {
            // This code should do things like set Animations, respond to input, and so on.
        }

        public virtual void Destroy()
        {
            base.Destroy();

            SpriteManager.RemoveSprite(_lock);
            SpriteManager.RemoveSprite(_levelNum1);
            SpriteManager.RemoveSprite(_levelNum10);
        }

        public void SetColor(int index)
        {
            if (index < 5)
            {
                _sprite.CurrentFrameIndex = index;
                _sprite.Visible = true;
            }
            else
            {
                _sprite.Visible = false;
            }
        }

        public void SetLocked(int numberRequired)
        {
            if (GameProperties.Save.TotalPoints < numberRequired)
            {
                _lock.Visible = true;
                _enabled = false;
            }
            else
            {
                _lock.Visible = false;
                _enabled = true;
            }
        }
        
        private AnimationChainList LoadColors()
        {
            AnimationChainList button = new AnimationChainList(5);
            AnimationChain buttons = new AnimationChain();
            buttons.Add(new AnimationFrame(@"Content/MenuObjects/LevelButtons/gold", 1.0f, "Global"));
            buttons.Add(new AnimationFrame(@"Content/MenuObjects/LevelButtons/silver", 1.0f, "Global"));
            buttons.Add(new AnimationFrame(@"Content/MenuObjects/LevelButtons/bronze", 1.0f, "Global"));
            buttons.Add(new AnimationFrame(@"Content/MenuObjects/LevelButtons/iron", 1.0f, "Global"));
            buttons.Add(new AnimationFrame(@"Content/MenuObjects/LevelButtons/incomplete", 1.0f, "Global"));

            button.Add(buttons);

            return button;
        }

        private string LoadNumber(int num)
        {
            return @"Content/MenuObjects/LevelButtons/" + num;
        }

        public virtual void FadeOut()
        {
            this.AlphaRate = -GameProperties.ALPHA_RATE;
            _partialFade = false;
        }

        public virtual void PartialFadeOut()
        {
            this.AlphaRate = -GameProperties.ALPHA_RATE;
            _partialFade = true;
        }

        public virtual void FadeIn()
        {
            this.AlphaRate = GameProperties.ALPHA_RATE;
        }

        public virtual bool DoneFading()
        {
            if (this.Alpha >= 1.0f && this.AlphaRate == GameProperties.ALPHA_RATE)
            {
                this.Alpha = 1.0f;
                this.AlphaRate = 0.0f;
                return true;
            }
            else if (_partialFade
                && this.Alpha <= .15f && this.AlphaRate == -GameProperties.ALPHA_RATE)
            {
                this.Alpha = .15f;
                this.AlphaRate = 0.0f;
                return true;
            }
            else if (!_partialFade
                && this.Alpha <= 0.0f && this.AlphaRate == -GameProperties.ALPHA_RATE)
            {
                this.Alpha = 0.0f;
                this.AlphaRate = 0.0f;
                return true;
            }
            else
            {
                return false;
            }
        }

        #endregion
    }
}
